package com.errol.batchprocessor.employeeaddition.advisorimpl.enhance;

import com.renjia.dao.CoreEmployeeImportBatchMapper;
import com.renjia.entity.CoreEmployeeImportBatch;
import com.renjia.service.generic.log.LogService;
import com.renjia.service.generic.middleware.batchprocessor.payload.AbstractBatchPayload;
import com.renjia.service.module.employeeaddition.advisor.*;
import com.renjia.service.module.employeeaddition.advisorimpl.EmployeeAdvisorTypeEnum;
import com.renjia.service.module.employeeaddition.advisorimpl.common.payload.AbstractEmployeeBatchPayload;
import com.renjia.service.module.employeeaddition.advisorimpl.common.payload.AbstractEmployeePiecePayload;
import com.renjia.service.module.employeeaddition.advisorimpl.common.payload.AbstractEmployeeSinglePayload;
import org.apache.commons.lang3.StringUtils;
import org.springframework.lang.NonNull;
import org.springframework.stereotype.Service;

/**
 * 人员导入过程统计值的计算
 * 因为这是辅助性的，可能不需要常驻执行，或者只需要统计第三方接口的调用即可，因此最终还是独立扩展
 *
 * @author zhang xiao bin
 * @version v1.0
 * @date 2021/03/15
 * @since v5.0.6
 **/
@Service
public class EmployeeAdditionCountAdvisorImpl<BE, SE, BP extends AbstractEmployeeBatchPayload<BE, SE>, PP extends AbstractEmployeePiecePayload<SE, SP>, SP extends AbstractEmployeeSinglePayload<SE>>
        implements
        EmployeeBatchPostAdvisor<BE, SE, BP, PP, SP>,
        EmployeePieceStartAdvisor<BE, SE, BP, PP, SP>, EmployeePiecePostAdvisor<BE, SE, BP, PP, SP>,
        EmployeeSingleStartAdvisor<BE, SE, BP, PP, SP>, EmployeeSinglePostAdvisor<BE, SE, BP, PP, SP> {

    private final CoreEmployeeImportBatchMapper coreEmployeeImportBatchMapper;
    private final LogService logService;

    public EmployeeAdditionCountAdvisorImpl(CoreEmployeeImportBatchMapper coreEmployeeImportBatchMapper, LogService logService) {
        this.coreEmployeeImportBatchMapper = coreEmployeeImportBatchMapper;
        this.logService = logService;
    }

    @Override
    public boolean shallProcess(@NonNull AbstractBatchPayload<CoreEmployeeImportBatch, EmployeeAdvisorTypeEnum, BE, SE> advisorPayload) {
        // > 0 表示导入，需要统计
        return advisorPayload.getAdvisorTypeEnum().getCode() > 0;
    }

    @Override
    public int priority() {
        return 41;
    }

    @Override
    public boolean doPrepareOnPieceStart(@NonNull PP piecePayload, @NonNull BP batchPayload) {
        piecePayload.initCountPayload();
        return true;
    }

    @Override
    public boolean doPrepareOnSingleStart(@NonNull SP singlePayload, @NonNull PP piecePayload, @NonNull BP batchPayload) {
        piecePayload.getCountPayload().setTimestamp();
        return true;
    }

    @Override
    public boolean doCleanUpOnSinglePost(@NonNull SP singlePayload, @NonNull PP piecePayload, @NonNull BP batchPayload) {
        if (singlePayload.getIsThreeElementSuccess() != null) {
            piecePayload.getCountPayload().addUpThreeElementCount();
            if (Boolean.TRUE.equals(singlePayload.getIsThreeElementSuccess())) {
                piecePayload.getCountPayload().addUpBankInfoCount();
            }
        }
        if (singlePayload.getCoreEmployeeCustomer() != null) {
            piecePayload.getCountPayload().addUpVerifyPassCount();
        }
        // 累计新增的实体类
        calculateNewEntities(singlePayload, piecePayload, batchPayload);
        return true;
    }

    @Override
    public boolean doCleanUpOnPiecePost(@NonNull PP piecePayload, @NonNull BP batchPayload) {
        if (piecePayload.getCountPayload() != null) {
            // 该扩展之前的分片启动失败，会导致该扩展分片启动不执行，此时 countPayload 为 null
            synchronized (batchPayload.getImportBatch()) {
                // 加锁后累计到 CoreEmployeeImportBatch
                CoreEmployeeImportBatch importBatch = batchPayload.getImportBatch();
                importBatch.setThreeElementCount(importBatch.getThreeElementCount() + piecePayload.getCountPayload().getThreeElementCount());
                importBatch.setBankInfoCount(importBatch.getBankInfoCount() + piecePayload.getCountPayload().getBankInfoCount());
                importBatch.setVerifyPassCount(importBatch.getVerifyPassCount() + piecePayload.getCountPayload().getVerifyPassCount());
                importBatch.setAddEmployeeCount(importBatch.getAddEmployeeCount() + piecePayload.getCountPayload().getAddEmployeeCount());
                importBatch.setAddEmployeeCustomerCount(importBatch.getAddEmployeeCustomerCount() + piecePayload.getCountPayload().getAddEmployeeCustomerCount());
                importBatch.setAddBankCardCount(importBatch.getAddBankCardCount() + piecePayload.getCountPayload().getAddBankCardCount());
                importBatch.setAddAgreementCount(importBatch.getAddAgreementCount() + piecePayload.getCountPayload().getAddAgreementCount());
            }
        }
        return true;
    }

    @Override
    public boolean doCleanUpOnBatchPost(@NonNull BP batchPayload) {
        if (StringUtils.isNotEmpty(batchPayload.getImportBatch().getId())) {
            // 即便整个批次被拦截，也依然会更新一次
            CoreEmployeeImportBatch importBatch = new CoreEmployeeImportBatch();
            importBatch.setId(batchPayload.getImportBatch().getId());
            importBatch.setThreeElementCount(batchPayload.getImportBatch().getThreeElementCount());
            importBatch.setBankInfoCount(batchPayload.getImportBatch().getBankInfoCount());
            importBatch.setVerifyPassCount(batchPayload.getImportBatch().getVerifyPassCount());
            importBatch.setAddEmployeeCount(batchPayload.getImportBatch().getAddEmployeeCount());
            importBatch.setAddEmployeeCustomerCount(batchPayload.getImportBatch().getAddEmployeeCustomerCount());
            importBatch.setAddBankCardCount(batchPayload.getImportBatch().getAddBankCardCount());
            importBatch.setAddAgreementCount(batchPayload.getImportBatch().getAddAgreementCount());
            importBatch.setUpdateUser(batchPayload.getCoreUser());
            try {
                coreEmployeeImportBatchMapper.updateById(importBatch);
            } catch (Exception e) {
                logService.error(e);
            }
        }
        return true;
    }

    private void calculateNewEntities(SP singlePayload, PP piecePayload, BP batchPayload) {
        if (singlePayload.getCoreEmployee() != null) {
            if (singlePayload.getCoreEmployee().getCreateTime() != null && singlePayload.getCoreEmployee().getCreateTime().getTime() > piecePayload.getCountPayload().getTimestamp()) {
                // coreEmployee 存在，且创建时间大于 pp 中记录的时间戳，认为是新建用户
                piecePayload.getCountPayload().addUpAddEmployeeCount();
                if (singlePayload.getCoreUserBank() != null) {
                    piecePayload.getCountPayload().addUpAddBankCardCount();
                }
                if (singlePayload.getCoreEmployeeCustomer() != null) {
                    piecePayload.getCountPayload().addUpAddEmployeeCustomerCount();
                    if (singlePayload.getCoreAgreementDetail() != null) {
                        piecePayload.getCountPayload().addUpAddAgreementCount();
                    }
                }
            } else {
                // coreEmployee 非新建用户
                if (singlePayload.getCoreUserBank() != null && singlePayload.getCoreUserBank().getCreateTime() != null
                        && singlePayload.getCoreUserBank().getCreateTime().getTime() > piecePayload.getCountPayload().getTimestamp()) {
                    piecePayload.getCountPayload().addUpAddBankCardCount();
                }
                if (singlePayload.getCoreEmployeeCustomer() != null && singlePayload.getCoreEmployeeCustomer().getCreateTime() != null
                        && singlePayload.getCoreEmployeeCustomer().getCreateTime().getTime() > piecePayload.getCountPayload().getTimestamp()) {
                    piecePayload.getCountPayload().addUpAddEmployeeCustomerCount();
                    if (singlePayload.getCoreAgreementDetail() != null) {
                        piecePayload.getCountPayload().addUpAddAgreementCount();
                    }
                }
            }
        }
    }
}
